# 1. Import  standard lib
from flask import Flask, redirect, url_for
from flask_login import current_user
from flask_principal import UserNeed, RoleNeed, identity_loaded

import os

# 2. Blueprint in the controllers.blog.py
from blog.controllers import blog_blueprint
from blog.controllers import main_blueprint


# 3.Module Created by oneself
from blog.models import db, User, Post, Role, Tag
from blog.controllers import blog
from blog.controllers.admin import CustomView, CustomModelView, CustomFileView
from blog.extensions import bcrypt, login_manager, openid, principals, flask_celery, flask_admin


#: Add BaseView to app
flask_admin.add_view( CustomView(name='Custom') )
	
#: Add ModelView to app
models = [Role, Tag, User, Post]

for model in models:
	flask_admin.add_view( CustomModelView(model, db.session, category='Models') )
	
#: Add FileView to app
flask_admin.add_view( CustomFileView(os.path.join(os.path.dirname(__file__), 'download'),
									'download',
									name='文件管理') )


#: Factory method used to create a `app`
def create_app(object_name):
	"""
	Create the app instance via `Factory Method`
	:param object_name:
	:return: initionaled app object
	"""

	#: Define app object , Default object_name value: blog.config.DevConfig
	app = Flask( __name__ )
	app.config.from_object( object_name )
	
	
	#: Init `flask_admin` object
	flask_admin.init_app( app )
	
	#: Init `celery` object
	flask_celery.init_app( app )
	
	#: Init `db` object
	db.init_app( app )

	#: Init the `bcrypt` via app object
	bcrypt.init_app( app )
	
	#: Init the `openid`
	openid.init_app( app )
	
	#: Init the `login_manaer`
	login_manager.init_app( app )
	
	#: Init the principals
	principals.init_app( app )
	
	#: Recived a single of identity_changed.send by `identity_loaded.connect_via(app), and loading the right	
	@identity_loaded.connect_via( app )
	def identity_loaded_app( sender, identity ):
		""" """
		
		identity.user = current_user
		
		if hasattr( current_user, 'id' ):
			identity.provides.add( UserNeed(current_user.id) )	
		if hasattr( current_user, 'roles' ):
			for role in current_user.roles:
				identity.provides.add( RoleNeed(role.name) )
	
	#: Registe the Blueprint
	app.register_blueprint( blog_blueprint )
	app.register_blueprint( main_blueprint )
	
	
	# Index view : seem to registe into app	
	@app.route( '/' )
	def index():
		home_url = url_for( 'blog.home' )
		return redirect( home_url )

	return app
